//
// Created by liuping on 2018/10/14.
//

#pragma once

#include <iterator>


template <typename T, int Size>
struct CircleQueueIter {
    typedef std::forward_iterator_tag  iterator_category;
    CircleQueueIter(T *q, int pos) : data(q), cur(pos) {}
    CircleQueueIter operator ++() {
        next();
        return *this;
    }
    CircleQueueIter operator ++(int) {
        CircleQueueIter t = *this;
        ++t;
        return t;
    }

    T *operator -> () {
        return &data[cur % Size];
    }
    T &operator *() {
        return *(this->operator->());
    }
    bool operator == (CircleQueueIter iter) {
        return data == iter.data && cur == iter.cur;
    }
    bool operator != (CircleQueueIter iter) {
        return iter.cur != cur || iter.data != data;
    }

    // 数据部分
    T *data;
    int cur = 0;
    void next() {
        cur++;
    }
};

template <typename T, int Size = 50>
class CircleQueue {
 public:
    void push(T &&data) {
        if (size() == Size) {
            pop();
        }
        queue[(head + len) % Size] = data;
        len++;
    }

    T pop() {
        int ret = head;
        head = (head + 1) % Size;
        len--;
        return queue[ret];
    }

    int size() {
        return len;
    }

    bool empty() {
        return size() == 0;
    }

    typedef CircleQueueIter<T, Size> iterator;
    iterator begin() {
        return iterator(queue, head);
    }
    iterator end() {
        return iterator(queue, head + len);
    }
 private:
    T queue[Size];
    int head = 0;
    int len = 0;
};


